package com.emagic.manage.mvp.presenters;

import com.emagic.manage.common.consts.SysParams;
import com.emagic.manage.data.exception.BizException;
import com.emagic.manage.mvp.domain.UseCase;
import com.emagic.manage.mvp.views.InterfaceView;
import com.emagic.manage.mvp.views.PageLimitView;
import com.fernandocejas.frodo.annotation.RxLogSubscriber;

import rx.Observer;
import rx.Subscriber;
import timber.log.Timber;

/**
 * TODO 描述该文件做什么
 *
 * @author baoy
 * @version 1.0
 *          Create by 2017/6/27 上午10:52
 */
public abstract class PageLimitPresenter<T> implements Presenter {

    protected PageLimitView<T> mPageView;
    private int pageOffset = 1;
    private int pageSize = SysParams.PAGE_DEFAULT_OFFSET;
    private int state = SysParams.LOAD_FIRST;

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    @Override
    public void attachView(InterfaceView v) {
        this.mPageView = (PageLimitView<T>) v;
    }

    protected abstract UseCase<T> buildPageUseCase(int pageOffset, int pageSize);

    protected Observer<T> buildObserver() {
        return null;
    }

    protected void errorFetch() {
        fetchFirst();
    }

    public void fetchFirst() {
        state = SysParams.LOAD_FIRST;
        pageOffset = 1;
        UseCase<T> useCase = buildPageUseCase(pageOffset, pageSize);
        Observer<T> observer = buildObserver();
        useCase.execute(new PageLimitSubscriber(mPageView, observer));

    }

    public void fetchTop() {
        state = SysParams.REFRESH;
        pageOffset = 1;
        UseCase<T> useCase = buildPageUseCase(pageOffset, pageSize);
        Observer<T> observer = buildObserver();
        useCase.execute(new PageLimitSubscriber(mPageView, observer));
    }

    public void fetchMore() {
        state = SysParams.LOAD_MORE;
        UseCase<T> useCase = buildPageUseCase(pageOffset, pageSize);
        Observer<T> observer = buildObserver();
        useCase.execute(new PageLimitSubscriber(mPageView, observer));
    }


    @RxLogSubscriber
    private class PageLimitSubscriber extends Subscriber<T> {

        private PageLimitView<T> pageLimitView;
        private Observer<T> pageObserver;

        public PageLimitSubscriber(PageLimitView<T> pageLimitView, Observer<T> pageObserver) {
            this.pageLimitView = pageLimitView;
            this.pageObserver = pageObserver;
        }

        @Override
        public void onStart() {
            super.onStart();
            pageOffset++;

            if (state == SysParams.LOAD_FIRST) {
                pageLimitView.showLoadingView();
            }
        }

        @Override
        public void onCompleted() {
            if (pageObserver != null) {
                pageObserver.onCompleted();
            }
        }

        @Override
        public void onError(Throwable throwable) {
            Timber.e(throwable);
            pageLimitView.onLoadingComplete();
            pageOffset--;
            if (pageOffset <= 1) {
                pageOffset = 1;
            }
            if (throwable instanceof BizException) {
                String code = ((BizException) throwable).code();
                if (code.equals("-2")) {
                    pageLimitView.onRefreshError("您的账号在其他设备登录");
                } else if (code.equals("1")) {
                    pageLimitView.onRefreshError("帐号未激活");
                } else if (code.equals("2")) {
                    pageLimitView.onRefreshError("帐号已冻结");
                } else if (code.equals("5")) {
                    pageLimitView.onRefreshError("密码错误");
                } else if (code.equals("6")) {
                    pageLimitView.onRefreshError("帐号不存在");
                } else {
                    pageLimitView.onRefreshError("服务端异常");
                }
            } else {
                pageLimitView.onRefreshError(throwable.getMessage());
            }

            if (pageObserver != null) {
                pageObserver.onError(throwable);
            }

        }

        @Override
        public void onNext(T t) {
            switch (state) {
                case SysParams.LOAD_FIRST:
                    pageLimitView.onLoadingComplete();
                    pageLimitView.render(t);
                    break;
                case SysParams.REFRESH:
                    pageLimitView.onRefreshComplete(t);
                    break;
                case SysParams.LOAD_MORE:
                    pageLimitView.onLoadMoreComplete(t);
                    break;
            }

            if (pageObserver != null) {
                pageObserver.onNext(t);
            }
        }
    }


}
